package co.yixiang.common.bean;

import co.yixiang.api.ApiCode;
import co.yixiang.api.UnAuthenticatedException;
import co.yixiang.common.util.JwtToken;
import co.yixiang.common.util.RequestUtils;
import co.yixiang.modules.user.domain.YxUser;
import com.auth0.jwt.interfaces.Claim;
import org.apache.commons.lang3.StringUtils;

import java.util.HashMap;
import java.util.Map;
import java.util.Optional;

/**
 * 全局user
 */
public class LocalUser {
    // 使用ThreadLocal存储用户信息，实现线程安全
    private static ThreadLocal<Map<String, Object>> threadLocal = new ThreadLocal<>();

    /**
     * 设置当前线程的用户信息和作用域
     * @param user 用户对象
     * @param scope 作用域
     */
    public static void set(YxUser user, Integer scope) {
        Map<String, Object> map = new HashMap<>();
        map.put("user", user);
        map.put("scope", scope);
        LocalUser.threadLocal.set(map);
    }

    /**
     * 清除当前线程的用户信息
     */
    public static void clear() {
        LocalUser.threadLocal.remove();
    }

    /**
     * 获取当前线程的用户对象
     * @return 用户对象
     */
    public static YxUser getUser() {
        Map<String, Object> map = LocalUser.threadLocal.get();
        YxUser user = (YxUser)map.get("user");
        return user;
    }

    /**
     * 获取当前线程的作用域
     * @return 作用域
     */
    public static Integer getScope() {
        Map<String, Object> map = LocalUser.threadLocal.get();
        Integer scope = (Integer)map.get("scope");
        return scope;
    }

    /**
     * 从token中获取用户ID
     * @return 用户ID
     * @throws UnAuthenticatedException 如果token验证失败，则抛出未认证异常
     */
    public static Long getUidByToken(){
        String bearerToken =  RequestUtils.getRequest().getHeader("Authorization");
        // 检查token是否为空或格式是否正确
        if (StringUtils.isEmpty(bearerToken) || !bearerToken.startsWith("Bearer")) {
            return 0L;
        }
        String[] tokens = bearerToken.split(" ");
        if (!(tokens.length == 2)) {
            return 0L;
        }
        String token = tokens[1];

        // 解析token并获取claims
        Optional<Map<String, Claim>> optionalMap = JwtToken.getClaims(token);
        Map<String, Claim> map = optionalMap
                .orElseThrow(() -> new UnAuthenticatedException(ApiCode.UNAUTHORIZED));

        // 从claims中获取用户ID并返回
        return  map.get("uid").asLong();
    }
}
